// PowerTest.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#include <iostream>
#include <pm.h>
#include "gtest/gtest.h"
using namespace std;

#define SETPOWERMANAGEMENT  6147

typedef struct _VIDEO_POWER_MANAGEMENT {
	ULONG Length;
	ULONG DPMSVersion;
	ULONG PowerState;
} VIDEO_POWER_MANAGEMENT, *PVIDEO_POWER_MANAGEMENT;

typedef enum _VIDEO_POWER_STATE {
	VideoPowerOn = 1,
	VideoPowerStandBy,
	VideoPowerSuspend,
	VideoPowerOff
} VIDEO_POWER_STATE, *PVIDEO_POWER_STATE;


class PowerManage
{
public:
	bool FullOn();
	bool UserIdle();
	bool SystemIdle();
	bool ScreenOff();
};

bool PowerManage::FullOn()
{
	cout<<"-----------Full On-----------"<<endl;
	if( SetDevicePower(L"BKL1:", POWER_NAME, D0)!=ERROR_SUCCESS)
	{
		cout<<"SetDevicePower full on error!"<<endl;
		return false;
	}
	else
	{
		cout<<"SetDevicePower full succeed!"<<endl;
		cout<<"Full On. This is the state in which the device is on and running. It is receiving full power from the system and is delivering full functionality to the user."<<endl;
		return true;
	}
}

bool PowerManage::UserIdle()
{
	cout<<"-----------User Idle-----------"<<endl;
	if( SetDevicePower(L"BKL1:", POWER_NAME, D1)!=ERROR_SUCCESS)
	{
		cout<<"SetDevicePower User Idle error!"<<endl;
		return false;
	}
	else
	{
		cout<<"SetDevicePower User Idle succeed!"<<endl;
		cout<<"Low On. This is the state in which the device is fully functional at a lower power state than D0, a lower performance state than D0, or both. This state is applicable when the device is being used, but where peak performance is unnecessary and power is at a premium."<<endl;
		return true;	
	}
}

bool PowerManage::SystemIdle()
{
	cout<<"-----------System Idle-----------"<<endl;
	if( SetDevicePower(L"BKL1:", POWER_NAME, D2)!=ERROR_SUCCESS)
	{
		cout<<"SetDevicePower System Idle error!"<<endl;
		return false;
	}
	else
	{
		cout<<"SetDevicePower System Idle succeed!"<<endl;
		cout<<"Standby. This is the state in which the device is partially powered with automatic wakeup on request. The device is effectively standing by."<<endl;
		return true;	
	}
}

bool PowerManage::ScreenOff()
{
	cout<<"-----------ScreenOff-----------"<<endl;

	VIDEO_POWER_MANAGEMENT vpm;
	HDC gdc;
	gdc = ::GetDC(NULL);
	vpm.Length = sizeof(VIDEO_POWER_MANAGEMENT);
	vpm.DPMSVersion = 0x0001;
	vpm.PowerState = VideoPowerOff;
	if(ExtEscape(gdc, SETPOWERMANAGEMENT, vpm.Length, (LPCSTR) &vpm, 0, NULL)>0)
	{
		::ReleaseDC(NULL, gdc);
		cout<<"Screen off succeed!"<<endl;
		Sleep(3000);
		vpm.PowerState = VideoPowerOn;
		if(ExtEscape(gdc, SETPOWERMANAGEMENT, vpm.Length, (LPCSTR) &vpm, 0, NULL)>0)
		{
			return true;
		}
		else
		{
			return false;
		}
		
	}
	else
	{
		cout<<"Screen off error!"<<endl;
		return false;
	}
}

int _tmain(int argc, _TCHAR* argv[])
{
	testing::InitGoogleTest(&argc, argv);
	return RUN_ALL_TESTS();
}

class PowerTest : public testing::Test
{
protected:
	static void SetUpTestCase()
	{
		pm = new PowerManage();
		cout<<"start"<<endl;
	}
	static void TearDownTestCase()
	{
		delete pm;
	}
	static PowerManage* pm;
};
PowerManage* PowerTest::pm = NULL;


TEST_F(PowerTest,UserIdle)
{
	EXPECT_EQ(true,pm->UserIdle());
	Sleep(3000);
}

TEST_F(PowerTest,SystemIdle)
{
	EXPECT_EQ(true,pm->SystemIdle());
	Sleep(3000);
}

TEST_F(PowerTest,ScreenOff)
{
	EXPECT_EQ(true,pm->ScreenOff());
	Sleep(3000);
}

TEST_F(PowerTest,FullOn)
{
	EXPECT_EQ(true,pm->FullOn());
	Sleep(3000);
}


